﻿using System.Collections;
using System.Collections.Generic;
using System.Threading;
using Porownywarka.Sortowanie;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Porownywarka.Interfejsy;

namespace UnitTests
{
    
    
    /// <summary>
    ///This is a test class for BubbleSortTest and is intended
    ///to contain all BubbleSortTest Unit Tests
    ///</summary>
    [TestClass()]
    public class BubbleSortTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for Sort
        ///</summary>
        public void SortTestHelper<T>(IComparer comparer)
            where T : IComparable<T>
        {
            //ISortMethod<T> target = new BubbleSort<T>(); // TODO: Initialize to an appropriate value
            ISortMethod<T> target = new QuickSort<T>();
            //ISortMethod<T> target = new HeapSort<T>();
            //ISortMethod<T> target = new MergeSort<T>();
            //ISortMethod<uint> target = new CountingSort<uint>();


            Random rand = new Random();
            for (int i = 0; i < 100; i++)
            {
                int size = rand.Next(1, 16);
                T[] arrayToTest = new T[size];

                for (int j = 0; j < size; j++)
                    arrayToTest[j] = Activator.CreateInstance<T>();

                T[] expected = (T[])arrayToTest.Clone();
                Array.Sort(expected);

                T[] testRes = target.Sort(arrayToTest);
                CollectionAssert.AreEqual(expected, testRes, comparer);
            }

        }

        public void SortTestHelper2()
        {
            ISortMethod<uint> target = new BubbleSort<uint>(); // TODO: Initialize to an appropriate value
            //ISortMethod<uint> target = new QuickSort<uint>();
            //ISortMethod<uint> target = new HeapSort<uint>();
            //ISortMethod<uint> target = new MergeSort<uint>();
            //ISortMethod<uint> target = new CountingSort<uint>();


            Random rand = new Random();
            for (int i = 0; i < 100; i++)
            {
                int size = rand.Next(1, 1600);
                uint[] arrayToTest = new uint[size];

                for (int j = 0; j < size; j++)
                    arrayToTest[j] = (uint)rand.Next(10000); //Activator.CreateInstance<T>();

                uint[] expected = (uint[])arrayToTest.Clone();
                Array.Sort(expected);

                uint[] testRes = target.Sort(arrayToTest);
                CollectionAssert.AreEqual(expected, testRes);
            }

        }

        [TestMethod()]
        public void SortTest()
        {

            //SortTestHelper<RandomContentObjct>(new ComparerHelper());
            SortTestHelper<int>(Comparer<int>.Default);
            SortTestHelper2();


        }
    }

    public class ComparerHelper : IComparer
    {
        public int Compare(object x, object y)
        {
            var c1 = x as RandomContentObjct;
            var c2 = y as RandomContentObjct;

            if (c1.Ticks < c2.Ticks)
                return -1;

            if (c1.Ticks > c2.Ticks)
                return 1;
            else
                return 0;
        }
    }

    public class RandomContentObjct : IComparable<RandomContentObjct>
    {
        private long tick;
        public long Ticks { get { return tick; } set { tick = value; } }

        public RandomContentObjct()
        {
            Thread.Sleep(10);
            tick = DateTime.Now.Ticks;
        }

        public int CompareTo(RandomContentObjct obj)
        {
            return Ticks.CompareTo(obj.Ticks);
        }
    }
}
